import QtQuick
import QtQuick.Controls
import QtQuick.Dialogs
import QtQuick.Layouts

import Fk
import Fk.Components.Common
import Fk.Widgets as W
import Fk.Components.GameCommon as Game

// TODO 现在还用不了这个
// import Fk.Components.Chess.Xiangqi
import "../../Components/Chess/Xiangqi"

W.PageBase {
  id: roomScene

  property bool inMyTurn: false
  property var selectedPiece: null
  property var pieces: ({})

  states: [
    State { name: "notactive" },
    State { name: "active" }
  ]

  state: "notactive"
  transitions: [
    Transition {
      from: "*"; to: "notactive"
      ScriptAction {
        script: {
          roomScene.deActivate();
        }
      }
    }
  ]

  Image {
    id: board
    source: Cpp.path + "/packages/chess-games/image/xiangqi/board.svg"
    width: 451
    height: 501
    anchors.centerIn: parent
    fillMode: Image.PreserveAspectFit

    Repeater {
      id: boradGridMarksRepeater
      model: 90
      Rectangle {
        color: "transparent"
        width: 50; height: 50; //radius: 100; // 20, 15; 10, 20
        x: (index % 9) * 50
        y: Math.floor(index / 9) * 50
        property int xPos: index % 9
        property int yPos: Math.floor(index / 9)
        property bool showMark: false 

        Image {
          id: trackMark
          source: Cpp.path + "/packages/chess-games/image/xiangqi/track_marker.svg"
          visible: parent.showMark
          anchors.fill: parent
        }

      }
    }

    // 定义棋盘上的90个交叉点
    Repeater {
      id: gridPoints
      model: 90
      Rectangle {
        color: "transparent"
        width: 50; height: 50; //radius: 100; // 20, 15; 10, 20
        x: (index % 9) * 50
        y: Math.floor(index / 9) * 50
        z: 5
        property int xPos: index % 9
        property int yPos: Math.floor(index / 9)
        property bool enabled: false

        Rectangle {
          width: 16
          height: 16
          radius: 8
          color: "white"
          opacity: 0.7
          anchors.centerIn: parent
          visible: parent.enabled
        }

        W.TapHandler {
          enabled: parent.enabled
          onTapped: {
            let luaPosId = (yPos + 1) * 10 + (xPos + 1)
            if (Lua.evaluate("Self.role") === "black") {
              luaPosId = (10 - yPos) * 10 + (9 - xPos);
            }
            Lua.call("UpdateRequestUI", "Xiangqi.PointItem", luaPosId, "click", {
              selected: true,
            } );
          }
        }
      }
    }
  }

  Photo {
    id: myPhoto
    anchors.left: board.right
    anchors.bottom: board.bottom
    anchors.leftMargin: 12

    onThinkingChanged: {
      if (!thinking) roomScene.deActivate();
    }
  }

  Photo {
    id: opponentPhoto
    anchors.right: board.left
    anchors.top: board.top
    anchors.rightMargin: 12
  }

  GlowText {
    visible: Config.observing && !Config.replaying
    anchors.right: board.left
    anchors.bottom: board.bottom
    anchors.rightMargin: 12
    text: Lua.tr("Observing ...")
    color: "#4B83CD"
    font.family: Config.li2Name
    font.pixelSize: 48
  }

  Rectangle {
    id: gameOverRect
    width: 200
    height: 200
    radius: 8
    color: "#AAFFFFFF"
    visible: false

    anchors.left: board.right
    anchors.top: board.top
    anchors.leftMargin: 12

    ColumnLayout {
      anchors.centerIn: parent
      width: parent.width
      spacing: 15

      Text {
        id: winnerText
        font.pixelSize: 24
        font.bold: true
        Layout.alignment: Qt.AlignHCenter
      }

      W.ButtonContent {
        Layout.alignment: Qt.AlignHCenter
        text: Lua.tr("Back To Room")
        visible: !Config.observing

        onClicked: {
          Mediator.notify(this, Command.ResetRoomPage);
        }
      }

      W.ButtonContent {
        text: Lua.tr("Back To Lobby")
        Layout.alignment: Qt.AlignHCenter

        onClicked: {
          Mediator.notify(this, Command.IWantToQuitRoom);
        }
      }

      W.ButtonContent {
        id: repBtn
        Layout.alignment: Qt.AlignHCenter
        text: Lua.tr("Save Replay")
        visible: Config.observing && !Config.replaying // 旁观

        onClicked: {
          repBtn.visible = false;
          Mediator.notify(this, Command.IWantToSaveRecord);
        }
      }

      W.ButtonContent {
        id: bkmBtn
        Layout.alignment: Qt.AlignHCenter
        text: Lua.tr("Bookmark Replay")
        visible: !Config.observing && !Config.replaying // 玩家

        onClicked: {
          bkmBtn.visible = false;
          Mediator.notify(this, Command.IWantToBookmarkRecord);
        }
      }
    }
  }

  // 将x和y对应到坐标
  // 若为黑方则翻转180度
  function convertPos(bX, bY) {
    let x = 50 * bX;
    let y = 50 * bY;

    if (Lua.evaluate("Self.role") === "black") {
      x = 400 - x;
      y = 450 - y;
    }

    return [x, y];
  }

  function getPhoto(id) {
    if (id == Self.id) return myPhoto;
    if (id == opponentPhoto.playerid) return opponentPhoto;
  }

  function selectPiece(piece) {
    Lua.call("UpdateRequestUI", "Xiangqi.PieceItem", piece.pieceId, "click", {
      selected: piece.selected,
    } );
  }

  // 根据玩家座位转换棋盘坐标
  function convertOrientation(position) {
    if (Self.seatNumber === 2) return position;
    return [10 - position[0], 9 - position[1]];
  }

  function applyChange(sender, uiUpdate) {
    uiUpdate["Xiangqi.PieceItem"]?.forEach(pdata => {
      const piece = pieces[pdata.id];
      piece.selectable = pdata.enabled;
      piece.selected = pdata.selected;
    });

    uiUpdate["_delete"]?.forEach(dat => {
      if (dat.type == "Xiangqi.PointItem") {
        const id = dat.id;
        const x = id % 10;
        const y = Math.floor(id / 10);
        let gridIdx = (y - 1) * 9 + (x - 1);
        if (Lua.evaluate("Self.role") === "black") {
          gridIdx = (10 - y) * 9 + (9 - x);
        }
        const item = gridPoints.itemAt(gridIdx);
        item.enabled = false;
      }
    });
    uiUpdate["_new"]?.forEach(dat => {
      if (dat.type === "Xiangqi.PointItem") {
        const id = dat.data.id;
        const x = id % 10;
        const y = Math.floor(id / 10);
        let gridIdx = (y - 1) * 9 + (x - 1);
        if (Lua.evaluate("Self.role") === "black") {
          gridIdx = (10 - y) * 9 + (9 - x);
        }
        const item = gridPoints.itemAt(gridIdx);
        item.enabled = true;
      }
    });
  }

  function syncBoard(sender, data) {
    const component = Qt.createComponent("../../Components/Chess/Xiangqi/Piece.qml");
    for (const id in pieces) {
      pieces[id].destroy();
      delete pieces[id];
    }
    pieces = {};

    for (let y = 0; y < 10; y++) {
      const xArr = data[y];
      for (let x = 0; x < 9; x++) {
        const id = data[y][x];
        if (id === 0) continue;

        const [xAxis, yAxis] = convertPos(x, y);
        const piece = component.createObject(board, {
          name: Lua.evaluate(`(function()
            local Xq = require "packages.chess-games.xiangqi"
            return Xq:getPieceById(${id}).name
          end)()`),
          pieceId: id,
          xPos: x,
          yPos: y,
          x: xAxis,
          y: yAxis,
        });
        piece.selectable = false;
        piece.clicked.connect(selectPiece);
        pieces[id] = piece;
        piece.goBackDuration = 200;
      }
    }
  }

  function playChess(sender, data) {
    roomScene.state = "active";
  }

  function deActivate() {
    for (const id in pieces) {
      pieces[id].selectable = false;
    }
    myPhoto.thinking = false;

    Lua.call("FinishRequestUI");
  }

  function movePieceTo(sender, data) {
    const [ pieceId, fromX, fromY, x, y ] = data;
    const piece = pieces[pieceId];
    const [xAxis, yAxis] = convertPos(x - 1, y - 1);
    for (const id in pieces) {
      if (id === pieceId) continue;
      const p = pieces[id];
      if (p.xPos === x - 1 && p.yPos === y - 1) {
        p.origOpacity = 0;
        p.origX = -50;
        p.origY = -50;
        p.destroyOnStop();
        p.goBack(true);
      }
    }

    const _fromX = piece.xPos
    const _fromY = piece.yPos

    piece.xPos = x - 1;
    piece.yPos = y - 1;
    piece.origX = xAxis;
    piece.origY = yAxis;
    piece.selected = false;
    piece.goBack(true);
    updatePieceTraker(_fromX, _fromY, x - 1, y - 1)
  }

  function updatePieceTraker(fromX, fromY, toX, toY) {
    for (let id = 0; id < 90; id++) {
      boradGridMarksRepeater.itemAt(id).showMark = false;
    }
    let fromId = fromY * 9 + fromX;
    let toId = toY * 9 + toX;
    if (Lua.evaluate("Self.role") === "black") {
      fromId = 89 - fromId
      toId = 89 - toId
    }
    boradGridMarksRepeater.itemAt(fromId).showMark = true
    boradGridMarksRepeater.itemAt(toId).showMark = true
  }

  function moveFocus(sender, data) {
    const focuses = data[0];
    const command = data[1];
    const timeout = data[2] ?? (Config.roomTimeout * 1000);

    myPhoto.thinking = false;
    opponentPhoto.thinking = false;

    const photo = getPhoto(focuses[0]);
    photo.duration = Math.floor(timeout / 1000);
    photo.thinking = true;
  }

  function propertyUpdate(sender, data) {
    const uid = data[0];
    const property_name = data[1];
    const value = data[2];

    if (property_name !== "role") return;
    const photo = getPhoto(uid);
    photo.role = value === "red" ? '<font color="red"><b>红方</b></font>' : "<b>黑方</b>"
  }

  function netStateChanged(sender, data) {
    const id = data[0];
    let state = data[1];

    const photo = getPhoto(id);
    const t = {
      "online": "在线",
      "offline": "离线",
      "run": "逃跑",
    };
    photo.netState = t[state];
  }

  function gameOver(sender, data) {
    winnerText.text = data === "red" ? "红方胜利" : "黑方胜利";
    gameOverRect.visible = true;
    Backend.playSound(`./packages/chess-games/audio/over`);
  }

  function doPlaySound(sender, data) {
    const type = data
    Backend.playSound(`./packages/chess-games/audio/${data}`);
  }

  Component.onCompleted: {
    addCallback("Xiangqi.SyncBoard", syncBoard);
    addCallback("Xiangqi.PlayChess", playChess);
    addCallback("Xiangqi.MovePieceTo", movePieceTo);
    addCallback("Xiangqi.PlaySound", doPlaySound);

    addCallback(Command.UpdateRequestUI, applyChange);
    addCallback(Command.MoveFocus, moveFocus);
    addCallback(Command.PropertyUpdate, propertyUpdate);
    addCallback(Command.NetStateChanged, netStateChanged);
    addCallback(Command.GameOver, gameOver);

    // 填写玩家信息，简单暴力的。。。
    const id1 = Lua.evaluate("ClientInstance.players[1].id");
    const id2 = Lua.evaluate("ClientInstance.players[2].id");
    for (const pid of [id1, id2]) {
      const item = pid === Self.id ? myPhoto : opponentPhoto;
      item.playerid = pid;
      item.screenName = Lua.evaluate(`ClientInstance:getPlayerById(${pid}).player:getScreenName()`);
      item.avatar = Lua.evaluate(`ClientInstance:getPlayerById(${pid}).player:getAvatar()`);
    }
  }
}
